import {Context, Next} from 'koa'
import jwt from 'jsonwebtoken'
import {IUser, IUserRes} from '@/types/user.types'
import {
  USERNAME_OR_PASSWORD_IS_REQUIRED,
  USER_DOES_NOT_EXISTS,
  PASSWORD_IS_INCORRECT,
  UNAUTHORIZED
} from '@/constants/error-types'
import service from '@/service/user.service'
import md5password from '@/utils/password-handle'
import {PUBLIC_KEY} from '@/app/config'

/**
 * 验证登录
 * @param ctx
 * @param next
 */
const verifyLogin = async (ctx: Context, next: Next): Promise<unknown> => {
  // 获取用户名密码
  const {username, password} = ctx.request.body as unknown as IUser

  // 判断用户名或者密码为空
  if (!username || !password) {
    const error: Error = new Error(USERNAME_OR_PASSWORD_IS_REQUIRED)
    return ctx.app.emit('error', ctx, error)
  }

  // 判断用户名是否存在
  const result: any = await service.getUserByName(username)
  const user: IUserRes = result[0][0]
  if (!user) {
    const error: Error = new Error(USER_DOES_NOT_EXISTS)
    return ctx.app.emit('error', ctx, error)
  }

  // 判断密码是否正确
  if (md5password(password) !== user.password) {
    const error: Error = new Error(PASSWORD_IS_INCORRECT)
    return ctx.app.emit('error', ctx, error)
  }

  // 将user赋值到ctx上
  ctx.user = user
  await next()
}

const vertifyAuth = async (ctx: Context, next: Next): Promise<unknown> => {
  const authorization = ctx.header.authorization
  // 获取token
  if (!authorization) {
    const error = new Error(UNAUTHORIZED)
    return ctx.app.emit('error', ctx, error)
  }

  // 验证token
  const token = authorization.replace('Bearer ', '')
  try {
    /**
     * result 示例
     * {
     *     id: 80050000000005,
     *     username: 'admin',
     *     iat: 1627782171,
     *     exp: 1627868571
     *  }
     */
    ctx.user = jwt.verify(token, PUBLIC_KEY, {
      algorithms: ['RS256']
    })
  } catch (e) {
    console.log(e)
    const error = new Error(UNAUTHORIZED)
    return ctx.app.emit('error', ctx, error)
  }
  await next()
}
export {
  verifyLogin,
  vertifyAuth
}